package com.mxx.bu_yang.activity.on_line;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.listener.OnItemChildClickListener;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.mxx.basic.server.RetrofitHelper;
import com.mxx.basic.server.enums.RequestEnum;
import com.mxx.basic.server.retrofit.observer.StringObserver;
import com.mxx.basic.utils.MapUrlParamsUtils;
import com.mxx.basic.utils.SPUtils;
import com.mxx.basic.utils.ToastUtils;
import com.mxx.bu_yang.R;
import com.mxx.bu_yang.ScannerService;
import com.mxx.bu_yang.activity.LoginActivity;
import com.mxx.bu_yang.adapter.CheckOrderAdapter;
import com.mxx.bu_yang.adapter.CheckResultAdapter;
import com.mxx.bu_yang.common.CommonTitleActivity;
import com.mxx.bu_yang.dialog.ScanSuccessDialog;
import com.mxx.bu_yang.dialog.WarehouseListDialog;
import com.mxx.bu_yang.response.CheckResultUpLoadRequest;
import com.mxx.bu_yang.response.MaterialCodeResponse;
import com.mxx.bu_yang.response.SourceOderResponse;
import com.mxx.bu_yang.response.WarehouseResponse;
import com.mxx.common.config.ConstantsConfig;
import com.mxx.common.config.NetUrlConfig;
import com.mxx.common.observer.CommonObserver;
import com.mxx.common.observer.DefaultListObserver;
import com.mxx.common.response.BaseEntityResponse;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 作者：刘江飞
 * 时间：2020/10/14  16:25
 * 邮箱：642371742Z@qq.com
 * 描述：货品盘点
 **/
public class GoodsCheckActivity extends CommonTitleActivity implements OnItemChildClickListener {
    private TextView tv_warehouse;
    private TextView tv_check_again;
    private TextView tv_cancel;
    private TextView tv_submit;
    private RecyclerView rv_check_result;
    private RecyclerView rv_goods_list;
    private CheckResultAdapter resultAdapter;
    private CheckOrderAdapter orderAdapter;
    private int tv_warehouse_height;
    private int tv_warehouse_width;
    private List<WarehouseResponse> list;
    private final Map<String, Object> paramsMap = new HashMap<>();
    private EditText edt_result;
    private ScanReceiver receiver;
    private TextWatcher textWatcher;

    @Override
    protected int getTitleType() {
        return TITLE_LEFT_BACK_MIDDLE_TITLE_RIGHT_TEXT;
    }

    /**
     * 获取当前页面的布局文件
     *
     * @return int
     */
    @Override
    public int getLayoutResId() {
        return R.layout.activity_goods_check;
    }

    @Override
    public void initView() {
        super.initView();
        tv_warehouse = findViewById(R.id.tv_warehouse);
        edt_result = findViewById(R.id.edt_result);
        rv_check_result = findViewById(R.id.rv_check_result);
        rv_goods_list = findViewById(R.id.rv_goods_list);
        tv_check_again = findViewById(R.id.tv_check_again);
        tv_cancel = findViewById(R.id.tv_cancel);
        tv_submit = findViewById(R.id.tv_submit);
        initResult();
        initOrder();
        tv_warehouse.post(() -> tv_warehouse_height = tv_warehouse.getHeight());
        tv_warehouse.post(() -> tv_warehouse_width = tv_warehouse.getWidth());

        tv_title.setText("货品盘点");
        tv_right.setText("已盘点");
        initReceiver();
        initTextWatcher();
    }

    private void initResult() {
        LinearLayoutManager mManager = new LinearLayoutManager(this);
        mManager.setOrientation(RecyclerView.HORIZONTAL);
        rv_check_result.setLayoutManager(mManager);
        resultAdapter = new CheckResultAdapter(R.layout.adapter_goods_batch);
        rv_check_result.setAdapter(resultAdapter);

    }

    private void initOrder() {
        LinearLayoutManager mManager = new LinearLayoutManager(this);
        mManager.setOrientation(RecyclerView.VERTICAL);
        rv_goods_list.setLayoutManager(mManager);
        orderAdapter = new CheckOrderAdapter(R.layout.adapter_goods_list);
        rv_goods_list.setAdapter(orderAdapter);
    }

    private void initReceiver() {
        receiver = new ScanReceiver();
        IntentFilter filter = new IntentFilter(ScannerService.ACTION);
        registerReceiver(receiver, filter);
    }

    private void initTextWatcher() {
        textWatcher = new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                Log.i("TAG", s.toString());
            }

            @Override
            public void onTextChanged(final CharSequence s, int start, int before, int count) {
                Log.i("TAG", s.toString());
            }

            @Override
            public void afterTextChanged(Editable s) {
                String barcode = s.toString();
                resetEditText();
                runOnUiThread(() -> {
                    if (!barcode.isEmpty()) {
                        paramsMap.put("barcode", barcode);
                        showScanSuccessDialog();
                    }
                });
            }
        };
    }

    @Override
    public void initData() {
        super.initData();
        loadGoodsBatchInfo(false);
    }

    private void loadGoodsBatchInfo(boolean showDialog) {
        int wareId = getWareId();
        paramsMap.put("wareId", String.valueOf(wareId));
        Map<String, String> request_params = new HashMap<>();
        request_params.put("wareId", String.valueOf(wareId));
        String json = "?" + MapUrlParamsUtils.getUrlParamsByMap(request_params);
        String baseUrl = (String) SPUtils.get(this, ConstantsConfig.BASE_URL, "");
        if (baseUrl == null || baseUrl.isEmpty()) {
            runOnUiThread(this::switchToLogin);
            return;
        }

        new RetrofitHelper
                .Builder()
                .baseUrl(baseUrl)
                .appendUrl("user/operationInventory/selStorageLocation" + json)
                .build()
                .observable(RequestEnum.METHOD_GET_NO_PARAMS)
                .subscribe(new DefaultListObserver(true, this) {
                    @Override
                    protected void handlerJsonArrayData(String arrayJson) {
                        list = paramsArrayJsonToList(arrayJson);
                        if (showDialog) {
                            showSelectWareHouseDialog();
                        }
                    }
                });


    }

    private List<WarehouseResponse> paramsArrayJsonToList(String arrayJson) {
        List<WarehouseResponse> list = new ArrayList<>();
        if (arrayJson != null && !arrayJson.isEmpty()) {
            list = new Gson().fromJson(arrayJson, new TypeToken<List<WarehouseResponse>>() {
            }.getType());
        }
        return list;
    }

    @Override
    public void initListener() {
        super.initListener();
        tv_warehouse.setOnClickListener(this);
        tv_check_again.setOnClickListener(this);
        tv_cancel.setOnClickListener(this);
        tv_submit.setOnClickListener(this);
        orderAdapter.setOnItemChildClickListener(this);
        edt_result.addTextChangedListener(textWatcher);
    }

    private void resetEditText() {
        edt_result.removeTextChangedListener(textWatcher);
        edt_result.setText("");
        edt_result.addTextChangedListener(textWatcher);
    }

    @Override
    protected void titleRightTextClick() {
        super.titleRightTextClick();
        int CHECK_IN_REQUEST_CODE = 1011;
        startActivityForResult(new Intent(this, GoodsCheckAlreadyActivity.class), CHECK_IN_REQUEST_CODE);
    }

    @Override
    public void onClick(View view) {
        super.onClick(view);
        if (view.getId() == R.id.tv_warehouse) {
            showSelectWareHouseDialog();
        }
        if (view.getId() == R.id.tv_check_again) {
            tv_warehouse.setText("");
            resetAllGoodsInfo();
        }
        if (view.getId() == R.id.tv_cancel) {
            finish();
        }
        if (view.getId() == R.id.tv_submit) {
            upload();
        }
    }


    private void showSelectWareHouseDialog() {
        if (list == null || list.isEmpty()) {
            loadGoodsBatchInfo(true);
        }
        int[] location = new int[2];
        tv_warehouse.getLocationOnScreen(location);
        tv_warehouse.getLocationOnScreen(location);
        WarehouseListDialog dialog = new WarehouseListDialog(tv_warehouse_width, location[0]
                , tv_warehouse_height, location[1], false);

        Bundle mBundle = new Bundle();
        mBundle.putSerializable("list", (Serializable) list);
        dialog.setArguments(mBundle);
        dialog.setBackDataListener(response -> {
            if (response == null) {
                ToastUtils.showToast(GoodsCheckActivity.this, "获取库位信息失败");
                return;
            }
            runOnUiThread(() -> tv_warehouse.setText(response.name));
            paramsMap.put("storeId", response.id);
            resetAllGoodsInfo();
            loadCheckResult(String.valueOf(response.id));
        });
        dialog.show(this.getSupportFragmentManager()
                , "BaseDialog");
    }

    private void loadCheckResult(String storeId) {
        if (storeId == null || storeId.isEmpty() || storeId.equals("-1")) {
            ToastUtils.showToast(this, "获取库位信息失败");
            return;
        }
        Map<String, String> request_params = new HashMap<>();
        request_params.put("storId", storeId);
        String json = "?" + MapUrlParamsUtils.getUrlParamsByMap(request_params);
        String baseUrl = (String) SPUtils.get(this, ConstantsConfig.BASE_URL, "");
        if (baseUrl == null || baseUrl.isEmpty()) {
            runOnUiThread(this::switchToLogin);
            return;
        }

        new RetrofitHelper
                .Builder()
                .baseUrl(baseUrl)
                .appendUrl("user/operationInventory/getInventoryResult" + json)
                .build()
                .observable(RequestEnum.METHOD_GET_NO_PARAMS)
                .subscribe(new DefaultListObserver(true, this) {
                    @Override
                    protected void handlerJsonArrayData(String arrayJson) {
                        List<MaterialCodeResponse> list = paramsArrayJsonToMaterialCodeList(arrayJson);
                        resultAdapter.setList(list);
                        orderAdapter.setList(list);
                    }
                });
    }

    private List<MaterialCodeResponse> paramsArrayJsonToMaterialCodeList(String arrayJson) {
        List<MaterialCodeResponse> list = new ArrayList<>();
        if (arrayJson != null && !arrayJson.isEmpty()) {
            list = new Gson().fromJson(arrayJson, new TypeToken<List<MaterialCodeResponse>>() {
            }.getType());
        }
        return list;
    }

    private void resetAllGoodsInfo() {
        resultAdapter.getData().clear();
        resultAdapter.notifyDataSetChanged();
        orderAdapter.getData().clear();
        orderAdapter.notifyDataSetChanged();

    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        int CHECK_IN_REQUEST_CODE = 1011;
        if (requestCode == CHECK_IN_REQUEST_CODE) {
            if (data == null) {
                return;
            }
            finish();
        }
    }

    private void showScanSuccessDialog() {
        ScanSuccessDialog successDialog = new ScanSuccessDialog();
        successDialog.setDialogDismissListener(dialog -> loadBarcodeInfo());
        successDialog.show(getSupportFragmentManager(), "ScanSuccessDialog");
    }

    private void loadBarcodeInfo() {
        String barcode = (String) paramsMap.get("barcode");
        if (barcode == null || barcode.isEmpty()) {
            ToastUtils.showToast(this, "获取条形码失败");
            return;
        }
        Map<String, String> request_params = new HashMap<>();
        request_params.put("barcode", barcode);
        String json = "?" + MapUrlParamsUtils.getUrlParamsByMap(request_params);
        String baseUrl = (String) SPUtils.get(this, ConstantsConfig.BASE_URL, "");
        if (baseUrl == null || baseUrl.isEmpty()) {
            runOnUiThread(this::switchToLogin);
            return;
        }

        new RetrofitHelper
                .Builder()
                .baseUrl(baseUrl)
                .appendUrl("user/operationInventory/getBarcode" + json)
                .build()
                .observable(RequestEnum.METHOD_GET_NO_PARAMS)
                .subscribe(new StringObserver(false, this) {
                    @Override
                    protected void onSuccess(String objectJson) {
                        Log.i("TAG", "");
                        refreshOrderAndResult(objectJson);
                    }

                    @Override
                    protected void onFailed(int code, String msg) {
                        super.onFailed(code, msg);
                        ToastUtils.showToast(GoodsCheckActivity.this, msg);
                    }
                });
    }

    private void refreshOrderAndResult(String objectJson) {
        String lotNum = getLotNum(objectJson);
        boolean exist = isExist(lotNum);
        if (exist) {
            refreshOrder(lotNum);
            refreshResult(lotNum);
        } else {
            addOrderData(lotNum);
            addResultData(lotNum);
        }
    }

    private boolean isExist(String objectJson) {
        if (objectJson == null || objectJson.isEmpty()) {
            return false;
        }
        List<MaterialCodeResponse> orderList = orderAdapter.getData();
        if (orderList.isEmpty()) {
            return false;
        }
        for (MaterialCodeResponse response : orderList) {
            String lotNo = response.lotNo;
            if (lotNo != null && !lotNo.isEmpty() && lotNo.equals(objectJson)) {
                return true;
            }
        }
        return false;
    }

    private String getLotNum(String objectJson) {
        BaseEntityResponse response = getBaseEntity(objectJson);
        Object data = null;
        try {
            data = response.data;
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (data == null) {
            ToastUtils.showToast(this, response.tip);
            return "";
        }
        return data.toString();
    }

    private BaseEntityResponse getBaseEntity(String objectJson) {
        BaseEntityResponse response = new BaseEntityResponse();
        if (objectJson != null && !objectJson.isEmpty()) {
            response = new Gson().fromJson(objectJson, new TypeToken<BaseEntityResponse>() {
            }.getType());
        }
        return response;
    }

    private void refreshOrder(String lotNum) {
        int order_position = getOrderPosition(lotNum);
        if (order_position != -1) {
            MaterialCodeResponse response = orderAdapter.getItem(order_position);
            int count;
            if (response.actualQty == null) {
                count = 0;
            } else {
                count = response.actualQty + 1;
            }
            response.actualQty = count;
            orderAdapter.notifyDataSetChanged();
        } else {
            MaterialCodeResponse response = new MaterialCodeResponse();
            response.lotNo = lotNum;
            response.stockQty = 0;
            response.actualQty = 1;
            orderAdapter.addData(response);
        }
    }

    private int getOrderPosition(String lotNum) {
        int position = -1;
        if (lotNum != null && !lotNum.isEmpty()) {
            List<MaterialCodeResponse> list = orderAdapter.getData();
            if (!list.isEmpty()) {
                for (MaterialCodeResponse response : list) {
                    if (response != null && response.lotNo != null && response.lotNo.equals(lotNum)) {
                        position = list.indexOf(response);
                    }
                }
            }
        }
        return position;
    }

    private void refreshResult(String lotNum) {
        int result_position = getResultPosition(lotNum);
        if (result_position != -1) {
            MaterialCodeResponse response = resultAdapter.getItem(result_position);
            int count;
            if (response.actualQty == null) {
                count = 0;
            } else {
                count = response.actualQty + 1;
            }
            response.actualQty = count;
            resultAdapter.notifyDataSetChanged();
        } else {
            MaterialCodeResponse response1 = new MaterialCodeResponse();
            response1.lotNo = lotNum;
            response1.stockQty = 0;
            response1.actualQty = 1;
            resultAdapter.addData(response1);
        }
    }

    private int getResultPosition(String lotNum) {
        int position = -1;
        if (lotNum != null && !lotNum.isEmpty()) {
            List<MaterialCodeResponse> list = resultAdapter.getData();
            if (!list.isEmpty()) {
                for (MaterialCodeResponse response : list) {
                    if (response != null && response.lotNo != null && response.lotNo.equals(lotNum)) {
                        position = list.indexOf(response);
                    }
                }
            }
        }
        return position;
    }

    private void addOrderData(String lotNum) {
        MaterialCodeResponse response = new MaterialCodeResponse();
        response.lotNo = lotNum;
        response.actualQty = 1;
        response.stockQty = 0;
        orderAdapter.addData(response);
    }

    private void addResultData(String lotNum) {
        MaterialCodeResponse response = new MaterialCodeResponse();
        response.lotNo = lotNum;
        response.actualQty = 1;
        response.stockQty = 0;
        resultAdapter.addData(response);
    }


    private void upload() {
        List<MaterialCodeResponse> list = orderAdapter.getData();
        if (list.isEmpty()) {
            ToastUtils.showToast(this, "请先获取盘点结果后再提交");
            return;
        }
        CheckResultUpLoadRequest upLoadRequest = new CheckResultUpLoadRequest();
        upLoadRequest.list = getUploadRequestList(list);
        upLoadRequest.result = getResult();
        upLoadRequest.storId = (Integer) paramsMap.get("storeId");
        upLoadRequest.userId = getLoginInfo().userId;
        upLoadRequest.userName = getLoginInfo().userName;
        String json = new Gson().toJson(upLoadRequest);
        String baseUrl = (String) SPUtils.get(this, ConstantsConfig.BASE_URL, "");
        if (baseUrl == null || baseUrl.isEmpty()) {
            runOnUiThread(this::switchToLogin);
            return;
        }

        new RetrofitHelper
                .Builder()
                .baseUrl(baseUrl)
                .appendUrl("user/operationInventory/submitInventory")
                .addParams(json)
                .build()
                .observable(RequestEnum.METHOD_POST_JSON_STRING)
                .subscribe(new CommonObserver(true, this) {
                    @Override
                    protected void handlerJsonData(String arrayJson) {
                        ToastUtils.showToast(GoodsCheckActivity.this, "成功");
                    }
                });
    }

    private List<MaterialCodeResponse> getUploadRequestList(List<MaterialCodeResponse> list) {
        List<MaterialCodeResponse> list1 = new ArrayList<>();
        if (list != null && !list.isEmpty()) {
            for (MaterialCodeResponse response : list) {
                MaterialCodeResponse response1 = new MaterialCodeResponse();
                response1.actualQty = response.actualQty;
                response1.difference = getDifference(response);
                response1.lotNo = response.lotNo;
                response1.stockQty = response.stockQty;
                list1.add(response1);
            }
        }
        return list1;
    }

    private String getDifference(MaterialCodeResponse response) {
        String des;
        Integer actualQty = response.actualQty;
        if (actualQty == null) {
            actualQty = 0;
        }
        Integer stockQty = response.stockQty;
        if (stockQty == null) {
            stockQty = 0;
        }
        if (stockQty >= actualQty) {
            des = "-" + (stockQty - actualQty);
        } else {
            des = "+" + (actualQty - stockQty);
        }
        return des;
    }

    private String getResult() {
        StringBuilder result = new StringBuilder();
        List<MaterialCodeResponse> list = resultAdapter.getData();
        if (!list.isEmpty()) {
            for (MaterialCodeResponse response : list) {
                if (response != null && response.lotNo != null) {
                    int index = list.indexOf(response);
                    Integer actualQty = response.actualQty;
                    if (actualQty == null) {
                        actualQty = 0;
                    }
                    Integer stockQty = response.stockQty;
                    if (stockQty == null) {
                        stockQty = 0;
                    }
                    String des;
                    if (stockQty >= actualQty) {
                        des = "少" + (stockQty - actualQty);
                    } else {
                        des = "多" + (actualQty - stockQty);
                    }
                    if (index == 0) {

                        result = new StringBuilder(response.lotNo + ":" + des);
                    } else {
                        result.append(",").append(response.lotNo).append(":").append(des);
                    }

                }
            }
        }
        return result.toString();
    }

    @Override
    public void onItemChildClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) {
        if (view.getId() == R.id.ll_source_info) {
            SourceOderResponse response = (SourceOderResponse) adapter.getItem(position);
            if (response == null) {
                ToastUtils.showToast(this, "获取物料信息失败");
                return;
            }
            String lotNo = response.lotNumber;
            String materielNumber = response.materialNumber;
            String wareId = (String) paramsMap.get("wareId");
            loadStotageDetail(lotNo, materielNumber, wareId);
        }
    }

    private void loadStotageDetail(String lotNo, String materielNumber, String wareId) {
        if (lotNo == null || materielNumber == null || wareId == null) {
            ToastUtils.showToast(this, "参数不足");
            return;
        }
        Map<String, String> request_params = new HashMap<>();
        request_params.put("lotNo", lotNo);
        request_params.put("materielNumber", materielNumber);
        request_params.put("wareId", wareId);
        String json = "?" + MapUrlParamsUtils.getUrlParamsByMap(request_params);
        String baseUrl = (String) SPUtils.get(this, ConstantsConfig.BASE_URL, "");
        if (baseUrl == null || baseUrl.isEmpty()) {
            runOnUiThread(this::switchToLogin);
            return;
        }

        new RetrofitHelper
                .Builder()
                .baseUrl(baseUrl)
                .appendUrl("user/operationMateriel/selMaterielStockDetail" + json)
                .build()
                .observable(RequestEnum.METHOD_GET_NO_PARAMS)
                .subscribe(new DefaultListObserver(true, this) {
                    @Override
                    protected void handlerJsonArrayData(String arrayJson) {
                        skipToStorageDetail(arrayJson);
                    }
                });
    }

    private void switchToLogin() {
        ToastUtils.showToast(this, "IP为空，请到登录页重新设置IP");
        SPUtils.put(this, "login_info", "");
        SPUtils.put(this, ConstantsConfig.BASE_URL, "");
        Intent mIntent = new Intent(this, LoginActivity.class);
        mIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(mIntent);
        finish();
    }

    private void skipToStorageDetail(String arrayJson) {
        ToastUtils.showToast(this, arrayJson);
    }

    public class ScanReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            Bundle bundle = intent.getExtras();
            edt_result.append(bundle.getString(ScannerService.BAR_CODE));
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        startMyService();
    }

    private void startMyService() {
        Intent intent = new Intent(this, ScannerService.class);
        startService(intent);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }
}
